package com.coffee.monitor.mina;

import java.io.IOException;

import org.apache.commons.lang3.StringUtils;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springside.modules.utils.Clock;

import com.coffee.monitor.entity.DataPoint;
import com.coffee.monitor.entity.Device;
import com.coffee.monitor.entity.Sensor;
import com.coffee.monitor.entity.User;
import com.coffee.monitor.service.account.AccountService;
import com.coffee.monitor.service.device.DataPointService;
import com.coffee.monitor.service.device.DeviceService;
import com.coffee.monitor.service.device.SensorService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * @Description: mina服务端业务处理类
 * @author coffee
 *
 */
@Component
public class ServerHandler extends IoHandlerAdapter {
	
	@Autowired
	private DeviceService deviceService;
	@Autowired
	private SensorService sensorService;
	@Autowired
	private AccountService accountService;
	@Autowired
	private DataPointService dataPointService;
	
	private Clock clock = Clock.DEFAULT;
	private final static Logger log = LoggerFactory.getLogger(ServerHandler.class);
	
	
	 public ServerHandler() {
	 }
	 @Override
	 public void exceptionCaught(IoSession session, Throwable cause)
	   throws Exception {
		 log.debug("通讯错误-------------"+cause.getMessage()+"---session--"+session.getId());
		 closeSession(session);
	 }
	 
	 
	 @Override
	 public void messageReceived(IoSession session, Object message)
	   throws Exception {
		 log.debug("服务端收到信息-------------");
		
		  //获取客户端发过来的key
		  String msg = message.toString();
		  Long deviceID= parseData(msg);
		  //保存客户端的会话session
		  if (deviceID!=null) {
			  SessionMap sessionMap = SessionMap.newInstance();
//			  log.debug("目前会话池里的session数量为-------------"+sessionMap.getSessionCount());
//			  log.debug("目前会话池里的ID数量为-------------"+sessionMap.getSessionCount());
//			  log.debug("目前会话实际数量为-------------"+session.);
			  IoSession old=sessionMap.getSession(deviceID);
			  //老session失效
			  if (old!=null&&old.getId()!=session.getId()) {
				old.close(true);
			  }
			  sessionMap.addSession(deviceID, session);
		  }
	  
	 }
	 @Override
	 public void messageSent(IoSession session, Object message) throws Exception {
		 log.debug("------------服务端发消息到客户端---");
	 }
	 @Override
	 public void sessionClosed(IoSession session) throws Exception {
		 log.debug("远程session关闭了一个..." + session.getRemoteAddress().toString());
		 closeSession(session);
	 }
	 @Override
	 public void sessionCreated(IoSession session) throws Exception {
		 log.debug(session.getRemoteAddress().toString() +"----------------------create");
	 }
	 @Override
	 public void sessionIdle(IoSession session, IdleStatus status)
	   throws Exception {
		 log.debug(session.getServiceAddress() +"--IDS--"+status);
		 closeSession(session);
	 }
	 @Override
	 public void sessionOpened(IoSession session) throws Exception {
		 log.debug("连接打开："+session.getLocalAddress());
	 }
	 private Long parseData(String msg){
//			{
//		    "apikey": "123",
//		    "method": "123",
//		    "device": 10,
//		    "sensor": 10,
//		    "timestamp": "123",
//		    "value": "123"
//		}
         try {
        	 ObjectMapper mapper = new ObjectMapper();  
			 JsonNode rootNode = mapper.readTree(msg);
			 String apiKey=rootNode.path("apikey").asText();
			 User user=accountService.findUserByApiKey(apiKey);
			 if (user==null) {
				return null;
			}
			 Long sensor=rootNode.path("sensor").asLong();
			 Sensor sen=sensorService.find(sensor);
			 if (sen==null) {
				 return null;
			 }
			 Long device=rootNode.path("device").asLong();
			 Device dv=deviceService.find(device);
			 String method=rootNode.path("method").asText();
			 String timestamp=rootNode.path("timestamp").asText();
			 String value=rootNode.path("value").asText();
			 //创建数据点
			 if (StringUtils.equals(method, "datapoint")) {
				 DataPoint dp=new DataPoint();
				 dp.setCreateDate(clock.getCurrentDate());
				 dp.setValue(value);
				 dp.setUserId(user.getId());
				 dp.setSensorId(sensor);
				 dataPointService.save(dp);
				 dv.setIsOnline(true);
				 dv.setOnlineDate(clock.getCurrentDate());
			 }
			 deviceService.save(dv);
			 return device;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		} 
	 }
	 private void closeSession(IoSession session){
		 //移除session 获取设备ID，将设备下线
		 SessionMap map=SessionMap.newInstance();
		 Long device=map.getDeviceBySessionId(session.getId());
		 map.remove(session.getId(), device);
		 session.close(true);
		 Device dv=deviceService.find(device);
		 if (dv!=null) {
			 dv.setIsOnline(false);
			 dv.setOfflineDate(clock.getCurrentDate());
			 deviceService.save(dv);
		 }
	 }
	}
